<template>
  <div ref="gameContainer" class="racing-game"></div>
</template>

<script>
import * as THREE from 'three';
import * as CANNON from 'cannon-es';
import { markRaw } from 'vue';

export default {
  name: 'RacingGame',
  mounted() {
    this.initGame();
    window.addEventListener('keydown', this.handleKeyDown);
    window.addEventListener('keyup', this.handleKeyUp);
  },
  beforeUnmount() {
    window.removeEventListener('keydown', this.handleKeyDown);
    window.removeEventListener('keyup', this.handleKeyUp);
    cancelAnimationFrame(this.animationFrameId);
  },
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      world: null,
      car: null,
      carBody: null,
      keys: {
        ArrowUp: false,
        ArrowDown: false,
        ArrowLeft: false,
        ArrowRight: false,
        w: false,
        s: false,
        a: false,
        d: false,
        W: false,
        S: false,
        A: false,
        D: false,
        ' ': false, // 空格键跳跃
        'Shift': false // Shift键加速
      },
      animationFrameId: null,
      health: 10,
      maxHealth: 10,
      obstacles: [],
      socialCars: [],
      trees: [],
      dynamicObstacles: [],
      lastTreeZ: 0,
      lastObstacleZ: 0
    };
  },
  computed: {
    healthText() {
      return `Health: ${this.health}/${this.maxHealth}`;
    }
  },
  methods: {
    initGame() {
      // 初始化Three.js场景 - 使用markRaw避免响应式代理
      this.scene = markRaw(new THREE.Scene());
      this.camera = markRaw(new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 5000));
      this.renderer = markRaw(new THREE.WebGLRenderer({ 
        antialias: true, 
        alpha: false,
        powerPreference: "high-performance",
        stencil: false,
        depth: true,
        preserveDrawingBuffer: true,
        premultipliedAlpha: false,
        logarithmicDepthBuffer: false
      }));
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.renderer.domElement.style.position = 'absolute';
      this.renderer.domElement.style.top = '0';
      this.renderer.domElement.style.left = '0';
      this.renderer.domElement.style.width = '100%';
      this.renderer.domElement.style.height = '100%';
      this.renderer.domElement.style.display = 'block';
      this.renderer.setClearColor(0x87ceeb, 1);
      this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
      this.renderer.outputColorSpace = THREE.SRGBColorSpace;
      this.renderer.shadowMap.enabled = false; // 禁用阴影以提高性能
      this.renderer.autoClear = true;
      this.$refs.gameContainer.appendChild(this.renderer.domElement);

      // 添加更大的天空盒
      const skyboxGeometry = markRaw(new THREE.BoxGeometry(4000, 4000, 4000));
      const skyboxMaterial = markRaw(new THREE.MeshBasicMaterial({
        color: 0x87ceeb,
        side: THREE.BackSide
      }));
      const skybox = markRaw(new THREE.Mesh(skyboxGeometry, skyboxMaterial));
      this.scene.add(skybox);

      // 初始化Cannon.js物理世界 - 使用markRaw避免响应式代理
      this.world = markRaw(new CANNON.World({
        gravity: new CANNON.Vec3(0, -9.82, 0)
      }));
      
      // 设置世界的默认接触材质以减少弹跳
      this.world.defaultContactMaterial.friction = 0.8;
      this.world.defaultContactMaterial.restitution = 0.1; // 降低弹性系数

      // 创建赛车
      this.createCar();

      // 创建赛道
      this.createTrack();

      // 初始化动态内容
      this.initializeDynamicContent();

      // 创建社会车辆
      this.createSocialCars(5);

      // 添加生命值文本
      this.addHealthText();

      // 设置相机位置
      this.camera.position.set(0, 5, 10);
      this.camera.lookAt(0, 0, 0);

      // 等待DOM完全加载后再开始渲染
      this.$nextTick(() => {
        // 预渲染多帧以避免闪屏
        for (let i = 0; i < 3; i++) {
          this.renderer.render(this.scene, this.camera);
        }
        
        // 立即启动动画循环
        this.animate();
      });
    },
    addHealthText() {
      // 在DOM中添加生命值显示
      const healthDiv = document.createElement('div');
      healthDiv.id = 'health-display';
      healthDiv.style.position = 'absolute';
      healthDiv.style.top = '20px';
      healthDiv.style.left = '20px';
      healthDiv.style.fontSize = '24px';
      healthDiv.style.color = 'white';
      healthDiv.style.fontFamily = 'Arial, sans-serif';
      healthDiv.style.zIndex = '100';
      document.body.appendChild(healthDiv);
    },
    createCar() {
      // 创建跑车模型组
      this.car = markRaw(new THREE.Group());
      
      // 主车身 - 跑车造型
      const bodyGeometry = markRaw(new THREE.BoxGeometry(2, 0.6, 4.5));
      const bodyMaterial = markRaw(new THREE.MeshBasicMaterial({ 
        color: 0xff0000,
        transparent: true,
        opacity: 0.9
      }));
      const body = markRaw(new THREE.Mesh(bodyGeometry, bodyMaterial));
      body.position.y = 0.3;
      this.car.add(body);
      
      // 驾驶舱
      const cabinGeometry = markRaw(new THREE.BoxGeometry(1.6, 0.8, 2));
      const cabinMaterial = markRaw(new THREE.MeshBasicMaterial({ 
        color: 0x333333,
        transparent: true,
        opacity: 0.7
      }));
      const cabin = markRaw(new THREE.Mesh(cabinGeometry, cabinMaterial));
      cabin.position.y = 0.9;
      cabin.position.z = -0.5;
      this.car.add(cabin);
      
      // 前保险杠
      const frontBumperGeometry = markRaw(new THREE.BoxGeometry(2.2, 0.3, 0.5));
      const frontBumperMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0xcc0000 }));
      const frontBumper = markRaw(new THREE.Mesh(frontBumperGeometry, frontBumperMaterial));
      frontBumper.position.y = 0.15;
      frontBumper.position.z = 2.5;
      this.car.add(frontBumper);
      
      // 后保险杠
      const rearBumperGeometry = markRaw(new THREE.BoxGeometry(2.2, 0.3, 0.5));
      const rearBumperMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0xcc0000 }));
      const rearBumper = markRaw(new THREE.Mesh(rearBumperGeometry, rearBumperMaterial));
      rearBumper.position.y = 0.15;
      rearBumper.position.z = -2.5;
      this.car.add(rearBumper);
      
      // 车轮
      const wheelGeometry = markRaw(new THREE.CylinderGeometry(0.4, 0.4, 0.3, 12));
      const wheelMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x222222 }));
      
      const wheelPositions = [
        [-1, 0.4, 1.8], [1, 0.4, 1.8],   // 前轮
        [-1, 0.4, -1.8], [1, 0.4, -1.8] // 后轮
      ];
      
      wheelPositions.forEach(pos => {
        const wheel = markRaw(new THREE.Mesh(wheelGeometry, wheelMaterial));
        wheel.rotation.z = Math.PI / 2;
        wheel.position.set(pos[0], pos[1], pos[2]);
        this.car.add(wheel);
      });
      
      // 前大灯
      const headlightGeometry = markRaw(new THREE.SphereGeometry(0.2, 8, 6));
      const headlightMaterial = markRaw(new THREE.MeshBasicMaterial({ 
        color: 0xffffaa,
        transparent: true,
        opacity: 0.8
      }));
      
      const leftHeadlight = markRaw(new THREE.Mesh(headlightGeometry, headlightMaterial));
      leftHeadlight.position.set(-0.7, 0.5, 2.3);
      this.car.add(leftHeadlight);
      
      const rightHeadlight = markRaw(new THREE.Mesh(headlightGeometry, headlightMaterial));
      rightHeadlight.position.set(0.7, 0.5, 2.3);
      this.car.add(rightHeadlight);
      
      // 尾灯
      const taillightGeometry = markRaw(new THREE.SphereGeometry(0.15, 8, 6));
      const taillightMaterial = markRaw(new THREE.MeshBasicMaterial({ 
        color: 0xff0000,
        transparent: true,
        opacity: 0.8
      }));
      
      const leftTaillight = markRaw(new THREE.Mesh(taillightGeometry, taillightMaterial));
      leftTaillight.position.set(-0.8, 0.4, -2.3);
      this.car.add(leftTaillight);
      
      const rightTaillight = markRaw(new THREE.Mesh(taillightGeometry, taillightMaterial));
      rightTaillight.position.set(0.8, 0.4, -2.3);
      this.car.add(rightTaillight);
      
      this.scene.add(this.car);

      // 赛车物理体 - 使用markRaw避免响应式代理
      const carShape = markRaw(new CANNON.Box(new CANNON.Vec3(0.5, 0.25, 1)));
      this.carBody = markRaw(new CANNON.Body({
        mass: 1,
        position: new CANNON.Vec3(0, 1, 0),
        shape: carShape
      }));
      
      // 设置车辆阻尼以减少弹跳和不稳定运动
      this.carBody.linearDamping = 0.4;  // 线性阻尼
      this.carBody.angularDamping = 0.8; // 角阻尼，防止翻转
      
      // 创建车辆专用材质
      const carMaterial = new CANNON.Material('car');
      carMaterial.friction = 0.8;
      carMaterial.restitution = 0.1; // 低弹性
      this.carBody.material = carMaterial;

      this.world.addBody(this.carBody);
    },
    createTrack() {
      // 创建更大的赛道地面
      for (let i = -10; i < 10; i++) {
        const groundGeometry = markRaw(new THREE.PlaneGeometry(100, 200));
        const groundMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x333333, side: THREE.DoubleSide }));
        const ground = markRaw(new THREE.Mesh(groundGeometry, groundMaterial));
        ground.rotation.x = Math.PI / 2;
        ground.position.z = i * 200;
        this.scene.add(ground);
      }

      // 创建带有白线纹理的道路 - 避免Z-fighting闪屏问题
      this.createRoadWithTexture();

      // 地面物理体 - 使用markRaw避免响应式代理
      const groundShape = markRaw(new CANNON.Plane());
      const groundBody = markRaw(new CANNON.Body({
        mass: 0,
        shape: groundShape
      }));
      
      // 创建地面材质
      const groundMaterial = new CANNON.Material('ground');
      groundMaterial.friction = 0.8;
      groundMaterial.restitution = 0.1; // 低弹性
      groundBody.material = groundMaterial;

      groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
      this.world.addBody(groundBody);
      
      // 创建车辆与地面的接触材质
      const carGroundContact = new CANNON.ContactMaterial(
        this.carBody.material,
        groundBody.material,
        {
          friction: 0.8,
          restitution: 0.05, // 极低弹性，几乎无弹跳
          contactEquationStiffness: 1e8,
          contactEquationRelaxation: 3
        }
      );
      this.world.addContactMaterial(carGroundContact);
    },
    createRoadWithTexture() {
      // 创建道路纹理，包含白色分隔线
      const canvas = document.createElement('canvas');
      canvas.width = 256;
      canvas.height = 256;
      const context = canvas.getContext('2d');
      
      // 绘制道路背景
      context.fillStyle = '#555555';
      context.fillRect(0, 0, 256, 256);
      
      // 绘制中央白线
      context.fillStyle = '#ffffff';
      const lineWidth = 8;
      const lineLength = 40;
      const lineGap = 20;
      
      // 绘制虚线效果
      for (let y = 0; y < 256; y += lineLength + lineGap) {
        context.fillRect(124, y, lineWidth, lineLength);
      }
      
      // 创建纹理
      const roadTexture = markRaw(new THREE.CanvasTexture(canvas));
      roadTexture.wrapS = THREE.RepeatWrapping;
      roadTexture.wrapT = THREE.RepeatWrapping;
      roadTexture.repeat.set(1, 20); // 重复纹理以创建长道路
      
      // 创建道路几何体和材质
      for (let i = -10; i < 10; i++) {
        const roadGeometry = markRaw(new THREE.PlaneGeometry(10, 200));
        const roadMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          map: roadTexture,
          side: THREE.DoubleSide,
          transparent: false,
          depthWrite: true,
          depthTest: true
        }));
        const road = markRaw(new THREE.Mesh(roadGeometry, roadMaterial));
        road.rotation.x = Math.PI / 2;
        road.position.z = i * 200;
        road.position.y = 0.01; // 稍微抬高避免与地面重叠
        this.scene.add(road);
      }
    },
    initializeDynamicContent() {
      // 初始化树木和障碍物
      this.lastTreeZ = -50;
      this.lastObstacleZ = -50;
      
      // 创建初始树木
      for (let i = -50; i < 100; i += 15) {
        this.createDynamicTree(-15, i);
        this.createDynamicTree(15, i);
      }
      
      // 创建初始障碍物
      for (let i = 0; i < 8; i++) {
        this.createDynamicObstacle();
      }
    },
    
    createDynamicTree(x, z) {
      const treeGroup = markRaw(new THREE.Group());
      
      // 树干
      const trunkGeometry = markRaw(new THREE.BoxGeometry(1, 3, 1));
      const trunkMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x8b4513 }));
      const trunk = markRaw(new THREE.Mesh(trunkGeometry, trunkMaterial));
      trunk.position.set(0, 1.5, 0);
      treeGroup.add(trunk);

      // 树叶
      const leavesGeometry = markRaw(new THREE.ConeGeometry(2, 4, 8));
      const leavesMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x228b22 }));
      const leaves = markRaw(new THREE.Mesh(leavesGeometry, leavesMaterial));
      leaves.position.set(0, 5, 0);
      treeGroup.add(leaves);
      
      treeGroup.position.set(x, 0, z);
      this.scene.add(treeGroup);

      // 树木物理体
      const treeShape = markRaw(new CANNON.Box(new CANNON.Vec3(0.5, 3, 0.5)));
      const treeBody = markRaw(new CANNON.Body({
        mass: 0,
        position: new CANNON.Vec3(x, 1.5, z),
        shape: treeShape
      }));
      this.world.addBody(treeBody);
      
      const treeData = { mesh: treeGroup, body: treeBody, z: z };
      this.trees.push(treeData);
      this.obstacles.push(treeBody);
      
      return treeData;
    },
    
    createDynamicObstacle() {
      const x = Math.random() * 8 - 4;
      const z = this.lastObstacleZ - Math.random() * 50 - 20;
      this.lastObstacleZ = z;
      
      const obstacle = this.createObstacleModel(x, z);
      const obstacleData = { mesh: obstacle.mesh, body: obstacle.body, z: z };
      this.dynamicObstacles.push(obstacleData);
      
      return obstacleData;
    },
    createTree(x, z) {
      // 树干
      const trunkGeometry = markRaw(new THREE.BoxGeometry(1, 3, 1));
      const trunkMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x8b4513 }));
      const trunk = markRaw(new THREE.Mesh(trunkGeometry, trunkMaterial));
      trunk.position.set(x, 1.5, z);
      this.scene.add(trunk);

      // 树叶
      const leavesGeometry = markRaw(new THREE.ConeGeometry(2, 4, 8));
      const leavesMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x228b22 }));
      const leaves = markRaw(new THREE.Mesh(leavesGeometry, leavesMaterial));
      leaves.position.set(x, 5, z);
      this.scene.add(leaves);

      // 树木物理体
      const treeShape = markRaw(new CANNON.Box(new CANNON.Vec3(0.5, 3, 0.5)));
      const treeBody = markRaw(new CANNON.Body({
        mass: 0,
        position: new CANNON.Vec3(x, 1.5, z),
        shape: treeShape
      }));
      this.world.addBody(treeBody);
      this.obstacles.push(treeBody);
    },
    createSocialCars(count) {
      // 创建社会车辆
      for (let i = 0; i < count; i++) {
        const x = Math.random() * 8 - 4; // -4 到 4 之间
        const z = Math.random() * -80 - 10; // -10 到 -90 之间
        const color = Math.random() * 0xffffff;

        // 社会车辆跑车模型
        const car = markRaw(new THREE.Group());
        
        // 主车身 - 跑车造型
        const bodyGeometry = markRaw(new THREE.BoxGeometry(1.8, 0.5, 4));
        const bodyMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          color,
          transparent: true,
          opacity: 0.9
        }));
        const body = markRaw(new THREE.Mesh(bodyGeometry, bodyMaterial));
        body.position.y = 0.25;
        car.add(body);
        
        // 驾驶舱
        const cabinGeometry = markRaw(new THREE.BoxGeometry(1.4, 0.6, 1.8));
        const cabinMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          color: color * 0.7,
          transparent: true,
          opacity: 0.8
        }));
        const cabin = markRaw(new THREE.Mesh(cabinGeometry, cabinMaterial));
        cabin.position.y = 0.65;
        cabin.position.z = -0.3;
        car.add(cabin);
        
        // 前保险杠
        const frontBumperGeometry = markRaw(new THREE.BoxGeometry(2, 0.25, 0.4));
        const frontBumperMaterial = markRaw(new THREE.MeshBasicMaterial({ color: color * 0.8 }));
        const frontBumper = markRaw(new THREE.Mesh(frontBumperGeometry, frontBumperMaterial));
        frontBumper.position.y = 0.125;
        frontBumper.position.z = 2.2;
        car.add(frontBumper);
        
        // 后保险杠
        const rearBumperGeometry = markRaw(new THREE.BoxGeometry(2, 0.25, 0.4));
        const rearBumperMaterial = markRaw(new THREE.MeshBasicMaterial({ color: color * 0.8 }));
        const rearBumper = markRaw(new THREE.Mesh(rearBumperGeometry, rearBumperMaterial));
        rearBumper.position.y = 0.125;
        rearBumper.position.z = -2.2;
        car.add(rearBumper);
        
        // 车轮
        const wheelGeometry = markRaw(new THREE.CylinderGeometry(0.35, 0.35, 0.25, 10));
        const wheelMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x222222 }));
        
        const wheelPositions = [
          [-0.9, 0.35, 1.6], [0.9, 0.35, 1.6],   // 前轮
          [-0.9, 0.35, -1.6], [0.9, 0.35, -1.6] // 后轮
        ];
        
        wheelPositions.forEach(pos => {
          const wheel = markRaw(new THREE.Mesh(wheelGeometry, wheelMaterial));
          wheel.rotation.z = Math.PI / 2;
          wheel.position.set(pos[0], pos[1], pos[2]);
          car.add(wheel);
        });
        
        // 前大灯
        const headlightGeometry = markRaw(new THREE.SphereGeometry(0.15, 6, 4));
        const headlightMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          color: 0xffffaa,
          transparent: true,
          opacity: 0.7
        }));
        
        const leftHeadlight = markRaw(new THREE.Mesh(headlightGeometry, headlightMaterial));
        leftHeadlight.position.set(-0.6, 0.4, 2.1);
        car.add(leftHeadlight);
        
        const rightHeadlight = markRaw(new THREE.Mesh(headlightGeometry, headlightMaterial));
        rightHeadlight.position.set(0.6, 0.4, 2.1);
        car.add(rightHeadlight);
        
        // 尾灯
        const taillightGeometry = markRaw(new THREE.SphereGeometry(0.12, 6, 4));
        const taillightMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          color: 0xff0000,
          transparent: true,
          opacity: 0.7
        }));
        
        const leftTaillight = markRaw(new THREE.Mesh(taillightGeometry, taillightMaterial));
        leftTaillight.position.set(-0.7, 0.35, -2.1);
        car.add(leftTaillight);
        
        const rightTaillight = markRaw(new THREE.Mesh(taillightGeometry, taillightMaterial));
        rightTaillight.position.set(0.7, 0.35, -2.1);
        car.add(rightTaillight);
        car.position.set(x, 0.5, z);
        this.scene.add(car);

        // 社会车辆物理体
        const carShape = markRaw(new CANNON.Box(new CANNON.Vec3(0.5, 0.25, 1)));
        const carBody = markRaw(new CANNON.Body({
          mass: 1,
          position: new CANNON.Vec3(x, 0.5, z),
          shape: carShape
        }));
        carBody.velocity.z = -1 - Math.random() * 2; // 随机速度
        this.world.addBody(carBody);

        this.socialCars.push({ mesh: car, body: carBody });
      }
    },
    createObstacleModel(x, z) {
      // 障碍物跑车模型 - 损坏的跑车作为障碍物
      const obstacle = markRaw(new THREE.Group());
      
      // 随机颜色
      const colors = [0x8B0000, 0x800080, 0x2F4F4F, 0x556B2F, 0x8B4513];
      const color = colors[Math.floor(Math.random() * colors.length)];
      
      // 主车身 - 损坏的跑车造型
      const bodyGeometry = markRaw(new THREE.BoxGeometry(1.6, 0.4, 3.5));
      const bodyMaterial = markRaw(new THREE.MeshBasicMaterial({ 
        color,
        transparent: true,
        opacity: 0.8
      }));
      const body = markRaw(new THREE.Mesh(bodyGeometry, bodyMaterial));
      body.position.y = 0.2;
      body.rotation.z = (Math.random() - 0.5) * 0.3; // 轻微倾斜
      obstacle.add(body);
      
      // 驾驶舱 - 破损效果
      const cabinGeometry = markRaw(new THREE.BoxGeometry(1.2, 0.5, 1.5));
      const cabinMaterial = markRaw(new THREE.MeshBasicMaterial({ 
        color: color * 0.6,
        transparent: true,
        opacity: 0.7
      }));
      const cabin = markRaw(new THREE.Mesh(cabinGeometry, cabinMaterial));
      cabin.position.y = 0.55;
      cabin.position.z = -0.2;
      cabin.rotation.z = (Math.random() - 0.5) * 0.2;
      obstacle.add(cabin);
      
      // 前保险杠 - 损坏状态
      const frontBumperGeometry = markRaw(new THREE.BoxGeometry(1.8, 0.2, 0.3));
      const frontBumperMaterial = markRaw(new THREE.MeshBasicMaterial({ color: color * 0.7 }));
      const frontBumper = markRaw(new THREE.Mesh(frontBumperGeometry, frontBumperMaterial));
      frontBumper.position.y = 0.1;
      frontBumper.position.z = 1.9;
      frontBumper.rotation.x = (Math.random() - 0.5) * 0.4;
      obstacle.add(frontBumper);
      
      // 车轮 - 部分缺失或损坏
      const wheelGeometry = markRaw(new THREE.CylinderGeometry(0.3, 0.3, 0.2, 8));
      const wheelMaterial = markRaw(new THREE.MeshBasicMaterial({ color: 0x333333 }));
      
      const wheelPositions = [
        [-0.8, 0.3, 1.4], [0.8, 0.3, 1.4],   // 前轮
        [-0.8, 0.3, -1.4], [0.8, 0.3, -1.4] // 后轮
      ];
      
      wheelPositions.forEach((pos, index) => {
        // 随机决定是否显示车轮（模拟损坏效果）
        if (Math.random() > 0.3) {
          const wheel = markRaw(new THREE.Mesh(wheelGeometry, wheelMaterial));
          wheel.rotation.z = Math.PI / 2;
          wheel.position.set(pos[0], pos[1], pos[2]);
          wheel.rotation.y = Math.random() * Math.PI;
          obstacle.add(wheel);
        }
      });
      
      // 破损的前大灯
      if (Math.random() > 0.5) {
        const headlightGeometry = markRaw(new THREE.SphereGeometry(0.12, 6, 4));
        const headlightMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          color: 0x444444,
          transparent: true,
          opacity: 0.5
        }));
        
        const leftHeadlight = markRaw(new THREE.Mesh(headlightGeometry, headlightMaterial));
        leftHeadlight.position.set(-0.5, 0.35, 1.8);
        obstacle.add(leftHeadlight);
      }
      
      // 烟雾效果（用小球体模拟）
      for (let i = 0; i < 3; i++) {
        const smokeGeometry = markRaw(new THREE.SphereGeometry(0.1 + Math.random() * 0.1, 4, 3));
        const smokeMaterial = markRaw(new THREE.MeshBasicMaterial({ 
          color: 0x666666,
          transparent: true,
          opacity: 0.3
        }));
        const smoke = markRaw(new THREE.Mesh(smokeGeometry, smokeMaterial));
        smoke.position.set(
          (Math.random() - 0.5) * 2,
          0.5 + Math.random() * 0.5,
          (Math.random() - 0.5) * 2
        );
        obstacle.add(smoke);
      }
      obstacle.position.set(x, 0.5, z);
      this.scene.add(obstacle);

      // 障碍物物理体
      const obstacleShape = markRaw(new CANNON.Box(new CANNON.Vec3(0.5, 0.5, 0.5)));
      const obstacleBody = markRaw(new CANNON.Body({
        mass: 0,
        position: new CANNON.Vec3(x, 0.5, z),
        shape: obstacleShape
      }));
      this.world.addBody(obstacleBody);
      this.obstacles.push(obstacleBody);
      
      return { mesh: obstacle, body: obstacleBody };
    },
    
    manageDynamicContent() {
      const carZ = this.car.position.z;
      
      // 动态生成前方的树木
      while (this.lastTreeZ > carZ - 200) {
        this.createDynamicTree(-15, this.lastTreeZ - 15);
        this.createDynamicTree(15, this.lastTreeZ - 15);
        this.lastTreeZ -= 15;
      }
      
      // 动态生成前方的障碍物
      if (Math.random() < 0.02 && this.lastObstacleZ > carZ - 150) {
        this.createDynamicObstacle();
      }
      
      // 清理后方的树木
      this.trees = this.trees.filter(tree => {
        if (tree.z > carZ + 100) {
          this.scene.remove(tree.mesh);
          this.world.removeBody(tree.body);
          // 从obstacles数组中移除
          const index = this.obstacles.indexOf(tree.body);
          if (index > -1) {
            this.obstacles.splice(index, 1);
          }
          return false;
        }
        return true;
      });
      
      // 清理后方的障碍物
      this.dynamicObstacles = this.dynamicObstacles.filter(obstacle => {
        if (obstacle.z > carZ + 100) {
          this.scene.remove(obstacle.mesh);
          this.world.removeBody(obstacle.body);
          // 从obstacles数组中移除
          const index = this.obstacles.indexOf(obstacle.body);
          if (index > -1) {
            this.obstacles.splice(index, 1);
          }
          return false;
        }
        return true;
      });
    },
    checkCollisions() {
      // 检测与社会车辆的碰撞
      for (const socialCar of this.socialCars) {
        const distance = this.carBody.position.distanceTo(socialCar.body.position);
        if (distance < 1.5) {
          this.damage(1);
          // 简单的碰撞响应
          this.carBody.velocity.z *= -0.5;
          socialCar.body.velocity.z *= -0.5;
          break;
        }
      }

      // 检测与障碍物的碰撞
      for (const obstacle of this.obstacles) {
        const distance = this.carBody.position.distanceTo(obstacle.position);
        if (distance < 1.5) {
          this.damage(1);
          // 简单的碰撞响应
          this.carBody.velocity.z *= -0.5;
          break;
        }
      }
    },
    damage(amount) {
      if (this.health > 0) {
        this.health -= amount;
        if (this.health <= 0) {
          this.health = 0;
          alert('Game Over!');
          cancelAnimationFrame(this.animationFrameId);
        }
        // 更新生命值显示
        document.getElementById('health-display').textContent = this.healthText;
      }
    },
    handleKeyDown(event) {
      if (this.keys.hasOwnProperty(event.key)) {
        this.keys[event.key] = true;
      }
      // 处理特殊键位
      if (event.code === 'Space') {
        event.preventDefault(); // 防止页面滚动
        this.keys[' '] = true;
      }
      if (event.key === 'Shift') {
        this.keys['Shift'] = true;
      }
    },
    handleKeyUp(event) {
      if (this.keys.hasOwnProperty(event.key)) {
        this.keys[event.key] = false;
      }
      // 处理特殊键位
      if (event.code === 'Space') {
        this.keys[' '] = false;
      }
      if (event.key === 'Shift') {
        this.keys['Shift'] = false;
      }
    },
    animate() {
      // 更新物理世界
      this.world.step(1 / 60);

      // 计算速度倍数（Shift键加速）
      const speedMultiplier = this.keys['Shift'] ? 2 : 1;
      
      // 控制赛车移动 - 支持方向键和WSAD键
      if (this.keys.ArrowUp || this.keys.w || this.keys.W) {
        this.carBody.velocity.z = -8 * speedMultiplier;
      } else if (this.keys.ArrowDown || this.keys.s || this.keys.S) {
        this.carBody.velocity.z = 5 * speedMultiplier;
      } else {
        this.carBody.velocity.z *= 0.95; // 轻微减速
      }

      if (this.keys.ArrowLeft || this.keys.a || this.keys.A) {
        this.carBody.velocity.x = -5 * speedMultiplier;
      } else if (this.keys.ArrowRight || this.keys.d || this.keys.D) {
        this.carBody.velocity.x = 5 * speedMultiplier;
      } else {
        this.carBody.velocity.x *= 0.9; // 轻微减速
      }
      
      // 空格键跳跃功能
      if (this.keys[' '] && this.carBody.position.y <= 1.2) { // 只有在接近地面时才能跳跃
        this.carBody.velocity.y = 8; // 向上跳跃
        this.keys[' '] = false; // 防止连续跳跃
      }

      // 限制赛车在道路范围内
      if (this.carBody.position.x > 5) this.carBody.position.x = 5;
      if (this.carBody.position.x < -5) this.carBody.position.x = -5;

      // 同步物理和渲染 - 只同步位置，不同步旋转以避免翻转
      this.car.position.set(
        this.carBody.position.x,
        this.carBody.position.y,
        this.carBody.position.z
      );
      // 保持车辆水平，不应用物理旋转
      this.car.rotation.set(0, 0, 0);

      // 更新社会车辆位置
      for (const socialCar of this.socialCars) {
        socialCar.mesh.position.set(
          socialCar.body.position.x,
          socialCar.body.position.y,
          socialCar.body.position.z
        );
        // 保持社会车辆水平，不应用物理旋转
        socialCar.mesh.rotation.set(0, 0, 0);

        // 社会车辆超出边界后重置
        if (socialCar.body.position.z > 50) {
          socialCar.body.position.z = Math.random() * -80 - 10;
          socialCar.body.position.x = Math.random() * 8 - 4;
          socialCar.body.velocity.z = -1 - Math.random() * 2;
        }
      }

      // 动态管理树木和障碍物
      this.manageDynamicContent();

      // 检查碰撞
      this.checkCollisions();

      // 更新相机位置，跟随赛车
      this.camera.position.x = this.car.position.x;
      this.camera.position.z = this.car.position.z + 10;
      this.camera.position.y = 5;
      this.camera.lookAt(this.car.position);

      // 渲染场景 - 直接使用主相机避免闪屏
      this.renderer.render(this.scene, this.camera);

      // 更新生命值显示
      document.getElementById('health-display').textContent = this.healthText;

      // 继续动画循环
      this.animationFrameId = requestAnimationFrame(this.animate);
    }
  }
};
</script>

<style scoped>
.racing-game {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
  z-index: 1;
}

/* 确保canvas元素完全覆盖屏幕 */
.racing-game canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100% !important;
  display: block;
  margin: 0;
  padding: 0;
}
</style>